package com.snpic.appaw.module.member.controller.app.login;

import cn.hutool.core.util.StrUtil;
import com.snpic.appaw.framework.common.pojo.CommonResult;
import com.snpic.appaw.framework.security.config.SecurityProperties;
import com.snpic.appaw.framework.security.core.util.SecurityFrameworkUtils;
import com.snpic.appaw.module.member.controller.app.login.vo.*;
import com.snpic.appaw.module.member.service.login.CustomerService;
import com.snpic.appaw.module.member.service.login.VerificationCodeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static com.snpic.appaw.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.snpic.appaw.framework.common.pojo.CommonResult.success;
import static com.snpic.appaw.module.member.enums.ErrorCodeConstants.*;

/**
 * @author JiJun
 * @date 2025/8/21 15:46
 * @description
 */
@Tag(name = "C端 - 用户")
@RestController
@RequestMapping("/member/customer")
@RequiredArgsConstructor
@Slf4j
@Validated
public class CustomerController {

	private final CustomerService customerService;

	private final VerificationCodeService verificationCodeService;


	private final SecurityProperties securityProperties;


	/**
	 * 发送登录验证码，发送手机短信
	 *
	 * @return 通用返回结果
	 */
	@GetMapping("/sendLoginCode")
	@Operation(summary = "发送登录验证码")
	@PermitAll
	public CommonResult<LoginCodeRespVO> snedLoginCode(@RequestParam String phone) {
		log.info("生成登录验证码，手机号：{}", phone);
		// 参数校验
		if (StrUtil.isBlank(phone)) {
			throw exception(PHONE_NOT_EXISTS);
		}
		// 生成并存储验证码,发送短信
		LoginCodeRespVO loginCodeRespVO = verificationCodeService.storeLoginCode(phone);

		return CommonResult.success(loginCodeRespVO, "手机号" + phone + "登录验证码生成成功");
	}


	/**
	 * 用户登录
	 * 替换原有Status返回为框架统一的R对象，使用DTO接收参数
	 */
	@PostMapping("/login")
	@Operation(summary = "用户登录")
	@PermitAll
	public CommonResult<LoginRespVO> login(@RequestBody @Valid LoginReqVO loginReqVO) {
		LoginRespVO loginRespVO = customerService.login(loginReqVO);

		log.info("调用返回loginRespVO={}", loginRespVO);
		return CommonResult.success(loginRespVO);
	}

	/**
	 * 生成修改密码验证码，发送手机短信
	 *
	 * @return 通用返回结果
	 */
	@GetMapping("/sendUpdatePasswordCode")
	@Operation(summary = "发送修改密码用验证码")
	@PermitAll
	public CommonResult<LoginCodeRespVO> sendUpdatePasswordCode(@RequestParam String phone) {
		log.info("生成修改密码验证码，手机号：{}", phone);
		// 参数校验
		if (StrUtil.isBlank(phone)) {
			throw exception(PHONE_NOT_EXISTS);
		}
		// 生成并存储验证码,发送短信
		LoginCodeRespVO loginCodeRespVO = verificationCodeService.storeUpdatePasswordCode(phone);

		return CommonResult.success(loginCodeRespVO, "手机号" + phone + "修改密码验证码生成成功");
	}

	/**
	 * 验证, 修改密码用验证码
	 *
	 * @param phone 手机号
	 * @param code  验证码
	 * @return 验证结果（true-验证成功，false-验证失败）
	 */
	@GetMapping("/verifyUpdatePasswordCode")
	@Operation(summary = "验证,修改密码用验证码")
	@PermitAll
	public CommonResult<String> verifyUpdatePasswordCode(@RequestParam String phone, @RequestParam String code) {
		log.info("验证修改密码验证码，手机号：{}", phone);
		// 参数校验
		if (StrUtil.isBlank(phone)) {
			throw exception(PHONE_NOT_EXISTS);
		}
		if (StrUtil.isBlank(code)) {
			throw exception(VERIFICATION_CODE_EMPTY);
		}
		// 调用服务层验证验证码
		String tempToken = verificationCodeService.verifyUpdatePasswordCode(phone, code);

		return CommonResult.success(tempToken, "验证码验证成功");

	}


	/**
	 * 修改用户密码（一年内不能重复）
	 *
	 * @param reqVO 请求参数（包含用户ID/用户名、旧密码、新密码）
	 */
	@PostMapping("/updatePassword")
	@Operation(summary = "修改用户密码")
	@PermitAll
	public CommonResult<Void> updatePassword(@Valid @RequestBody UpdatePwdReqVO reqVO) {
		// 参数校验@Valid
		// 调用Service处理密码修改逻辑
		boolean isSuccess = customerService.updatePassword(reqVO);
		if (isSuccess) {
			return CommonResult.success(null, "修改成功");
		} else {
			return CommonResult.error(PASSWORD_UPDATE_FAILED);
		}
	}

	/**
	 * 用户登出（从请求头获取token）
	 * 使当前用户的token失效
	 */
	@PostMapping("/logout")
	@Operation(summary = "用户登出", description = "token需放在请求头Authorization中，格式：Bearer <token>")
	public CommonResult<Boolean> logout(HttpServletRequest request) {
		log.info("用户登出请求，Authorization头：{}", request);
		String token = SecurityFrameworkUtils.obtainAuthorization(request,
			securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
		if (StrUtil.isNotBlank(token)) {
			customerService.logout(token);
		} else {
			throw exception(TOKEN_NOT_EXIST);
		}
		return success(true);

	}

	@GetMapping("/getCustomer")
	@Operation(summary = "获取登录用户信息")
	public CommonResult<ECusomterVO> getCurrentUser() {
		ECusomterVO eCusomterVO = customerService.getCurrentUser();
		return CommonResult.success(eCusomterVO);
	}

}